package com.xzq.bugstack.server;

import com.alibaba.fastjson.JSON;
import com.xzq.bugstack.domain.*;
import com.xzq.bugstack.util.CacheUtil;
import com.xzq.bugstack.util.FileUtil;
import com.xzq.bugstack.util.MsgUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author xzq
 * @Description //TODO
 * @Date 2021/11/20 17:56
 * @Version 1.0.0
 **/
public class MyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel sc = (SocketChannel) ctx.channel();
        System.out.println("连接建立....");
        System.out.println("客户端IP: " + sc.localAddress().getHostString());
        System.out.println("客户端端口: " + sc.localAddress().getPort());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            //数据格式验证
        if (!(msg instanceof FileTransferProtocol)) {return;}
        FileTransferProtocol fileTransferProtocol = (FileTransferProtocol) msg;
        // 0传输文件请求，1 文件传输指令 2文件传输数据
        switch (fileTransferProtocol.getTransferType()) {
            case 0:
                FileDescInfo fileDescInfo = (FileDescInfo) fileTransferProtocol.getTranferObj();
                //断电续传信息，实际应用中需要将断电续传信息保存到数据库中
                FileBurstInstruct fileBurstInstructOld = CacheUtil.burstDataMap.get(fileDescInfo.getFileName());
                if (null != fileBurstInstructOld) {
                    if (fileBurstInstructOld.getStatus() == Constants.FileStatus.COMPLETE) {
                        CacheUtil.burstDataMap.remove(fileDescInfo.getFileName());
                    }
                    //传输完成删除断点信息
                    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"xzq 服务端，接收客户端传输文件请求[断点续传]"+ JSON.toJSONString(fileBurstInstructOld));
                    ctx.writeAndFlush(MsgUtil.buildTransferInstruct(fileBurstInstructOld));
                    return;
                }
                //发送信息
                FileTransferProtocol sendFileTransferProtocol = MsgUtil.buildTransferInstruct(Constants.FileStatus.BEGIN, fileDescInfo.getFileUrl(), 0);
                ctx.writeAndFlush(sendFileTransferProtocol);
                System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"xzq 服务端，接收客户端传输文件请求"+JSON.toJSONString(fileDescInfo));
                break;
            case 2:
                FileBurstData fileBurstData = (FileBurstData) fileTransferProtocol.getTranferObj();
                FileBurstInstruct fileBurstInstruct = FileUtil.writeFile("F:\\upload", fileBurstData);

                //保存断电续传信息
                CacheUtil.burstDataMap.put(fileBurstData.getFileName(), fileBurstInstruct);

                ctx.writeAndFlush(MsgUtil.buildTransferInstruct(fileBurstInstruct));
                System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"xzq 服务端，接收客户端传输文件数据,当前分片数据大小："+fileBurstData.getBytes().length+"字节");

                //传输完成删除断点信息
                if (fileBurstInstruct.getStatus() == Constants.FileStatus.COMPLETE) {
                    CacheUtil.burstDataMap.remove(fileBurstData.getFileName());
                }
                break;
            default:
                break;
        }


    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        System.out.println("连接异常： \r\n" + cause.getMessage());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接断开: " + ctx.channel().localAddress().toString());
    }
}
